package cn.wp.ewallet.upms.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.wp.common.core.authentication.AuthenticationContext;
import cn.wp.common.core.authentication.AuthenticationInfo;
import cn.wp.common.core.authentication.UsernamePasswordToken;
import cn.wp.common.core.dto.WpResult;
import cn.wp.common.core.exception.WpAuthenticationException;
import cn.wp.common.core.id.Id;
import cn.wp.common.core.model.WpState;
import cn.wp.common.core.module.login.GenericLoginService;
import cn.wp.common.core.plugin.verification.VerificationCodeService;
import cn.wp.common.core.util.BCryptPasswordEncoder;
import cn.wp.common.core.util.IpUtil;
import cn.wp.common.core.web.WpWebContext;
import cn.wp.ewallet.common.model.EwalletAuthenticationInfo;
import cn.wp.ewallet.upms.dao.*;
import cn.wp.ewallet.upms.model.entity.LoginLogDo;
import cn.wp.ewallet.upms.model.entity.SysLoginUserDoo;
import cn.wp.ewallet.upms.model.entity.SystemUserInfoDo;
import cn.wp.ewallet.upms.service.WalletLoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service("adminLoginService")
@Slf4j
public class WalletAdminLoginServiceImpl extends GenericLoginService implements WalletLoginService {

    @Autowired
    private LoginLogDao loginLogDao;

    @Autowired
    private SysLoginUserDoDao sysLoginUserDoDao;

    @Autowired
    private VerificationCodeService verificationCodeService;

    @Override
    public UsernamePasswordToken createUsernamePasswordToken(String username) {
        List<SysLoginUserDoo> list = sysLoginUserDoDao.selectLoginUserDooByAccount(username);
        if (list.size() == 0) {
            return null;
        }
        String encodePassword = list.get(0).getPassword();
        String userId = list.get(0).getSysUserId();
        return new UsernamePasswordToken(username, encodePassword);
    }

    @Override
    public AuthenticationInfo loadUserByUsername(String username) {
        // 验证码校验
        String code = WpWebContext.getRequest().getParameter("code");
        if (StrUtil.isNotBlank(code)) {
            String randomStr = WpWebContext.getRequest().getParameter("randomStr");
            /*boolean check = verificationCodeService.checkCode(randomStr, code);
            if (!check) {
                throw new WpAuthenticationException(1001, "验证码错误");
            }*/
            WpState wpState = verificationCodeService.checkCodeState(randomStr,code);
            if(wpState.getCode()  > 0){
                throw new WpAuthenticationException(wpState.getCode(),wpState.getMessage());
            }
        }

        EwalletAuthenticationInfo authenticationInfo = new EwalletAuthenticationInfo();
        List<SysLoginUserDoo> list = sysLoginUserDoDao.selectLoginUserDooByAccount(username);
        if (list.size() == 0) {
            log.info("该管理员没有注册");
            return null;
        }

        SysLoginUserDoo loginUserDoo = list.get(0);
        authenticationInfo.setId(loginUserDoo.getSysUserId());
        authenticationInfo.setAccount(username);
        List<String> roleIds = new ArrayList<>();
        roleIds.add(loginUserDoo.getRoleId());
        authenticationInfo.setRoleIds(roleIds);
        List<String> roleNames = new ArrayList<>();
        roleNames.add(loginUserDoo.getRoleName());
        authenticationInfo.setRoleNames(roleNames);
        return authenticationInfo;
    }

    @Override
    public void onLoginSuccess(AuthenticationInfo authenticationInfo) {
        log.info("[ " + authenticationInfo.getAccount() + " ]登录成功");
        String uuid = WpWebContext.getRequest().getHeader("uuid");
        LoginLogDo loginLogDo = new LoginLogDo();
        loginLogDo.setLogId(Id.gen());
        if (authenticationInfo.getPhone() != null) {
            loginLogDo.setAccountNo(authenticationInfo.getPhone());
        } else {
            loginLogDo.setAccountNo(authenticationInfo.getAccount());
        }
        loginLogDo.setIpAddress(IpUtil.getIpAddress(WpWebContext.getRequest()));
        loginLogDo.setIsSuccess(0);
        loginLogDo.setLoginTime(DateUtil.date());
        loginLogDo.setImeiNo(uuid);
        loginLogDao.insertLoginLog(loginLogDo);

        // 最后登录设备添加到缓存
        loginLogDao.insertLoginEquipment(authenticationInfo.getAccount(), uuid);
    }

    @Override
    public void onLoginFailure(String phone, WpAuthenticationException ex) {
        log.error("[ " + phone + " ]登录失败,原因：" + ex.getMessage());
        LoginLogDo loginLogDo = new LoginLogDo();
        loginLogDo.setLogId(Id.gen());
        loginLogDo.setAccountNo(phone);
        loginLogDo.setIpAddress(IpUtil.getIpAddress(WpWebContext.getRequest()));
        loginLogDo.setIsSuccess(1);
        loginLogDo.setLoginTime(DateUtil.date());
        loginLogDo.setImeiNo(WpWebContext.getRequest().getHeader("uuid"));
        loginLogDo.setFailCause(ex.getMessage());
        loginLogDao.insertLoginLog(loginLogDo);
    }

    @Override
    public void onLogoutSuccess(AuthenticationInfo authenticationInfo) {
        System.err.println("注销登录成功");
    }

    @Override
    public WpResult modifyPassword(String oldPassword, String newPassword) {
        AuthenticationInfo authenticationInfo = AuthenticationContext.self().currentUser();
        String userId = authenticationInfo.getId();
        SystemUserInfoDo systemUserInfoDo = sysLoginUserDoDao.selectLoginUserDoByUserId(userId);
        //原密码校验
        boolean matches = BCryptPasswordEncoder.getInstance().matches(oldPassword, systemUserInfoDo.getPassword());
        if (matches) {
            systemUserInfoDo.setSysUserId(userId);
            systemUserInfoDo.setPassword(BCryptPasswordEncoder.getInstance().encode(newPassword));
            systemUserInfoDo.setUpdateDate(new Date());
            systemUserInfoDo.setUpdateUser(userId);
            sysLoginUserDoDao.updatePassword(systemUserInfoDo);
            return new WpResult().success();
        } else {
            return new WpResult().failure(1,"原密码不正确");
        }
    }

}